<?php

namespace JsonLowCode\UI;

use JsonLowCode\Helps\Random;
use JsonLowCode\UI;
use JsonLowCode\Schema;
use JsonLowCode\Traits\HasLifeCycle;

/**
 * Page组件
 * @method static Page make(mixed $children = null) Page组件
 */
class Page extends Schema
{
    protected string $componentName = "Page";

    //远程数据源
    private array $dataSource = [];
    //本地数据源
    private array $state = [];
    //组件生命周期
    private $lifeCycles = [];
    //组件方法
    private array $methods = [];

    private array $setupMethods = [];


    use HasLifeCycle;

    /**
     * @param mixed|null $children
     */
    public function __construct(mixed $children = null)
    {
        parent::__construct();
        $this->children($children);
    }



    /**
     * 设置组件样式
     * @param string $css
     * @return $this
     */
    public function css(string $css): static
    {
        return $this->setAttribute('css', $css);
    }

    /**
     * 设置远程数据源
     * @param string $key 键
     * @param mixed $value 远程数据
     * @return $this
     */
    public function dataSource(string $key, mixed $value): static
    {
        $this->dataSource[$key] = $value;
        $dataSource = ['list'=>array_values($this->dataSource)];
        return $this->setAttribute('dataSource',$dataSource);
    }

    /**
     * 设置本地数据源
     * @param string $key 函数名
     * @param mixed $value 完整的函数
     * @param bool $isJSExpression 是否js表达式
     * @return $this
     */
    public function state(string $key, mixed $value, bool $isJSExpression = false): static
    {
        $this->state[$key] = $isJSExpression?JSExpression($value):$value;
        return $this->setAttribute('state',$this->state);
    }

    /**
     * 设置本地数据源
     * @param string $key 函数名
     * @param mixed $value 完整的函数
     * @return $this
     */
    public function stateFunc(string $key, mixed $value): static
    {
        $this->state[$key] = JSFunction($value);
        return $this->setAttribute('state',$this->state);
    }

    /**
     * 设置方法
     * @param string $key 函数名
     * @param string $value 完整的函数
     * @return $this
     */
    public function methods(string $key, string $value): static
    {
        $this->methods[$key] = JSFunction($value);
        return $this->setAttribute('methods',$this->methods);
    }

    /**
     * @param string $script
     * @return $this
     */
    public function setupScript(string $script):static
    {
        $this->setupMethods[] = $script;
        return $this;
    }

    /**
     * @param string $watch
     * @param string $callback
     * @param array $options ['deep'=>true]
     * @return $this
     */
    public function watch(string $watch,string $callback, array $options = []):static
    {
        $options = json_encode($options,JSON_UNESCAPED_UNICODE);
        return $this->setupScript("setup.watch(() => $watch, $callback, $options)");
    }
//
//    /**
//     * 处理states数据
//     * @return void
//     */
//    private function initHandler(): void
//    {
//        $states = UI::getPageState();
//        $methods = UI::getPageMethod();
//        $sourceList = UI::getPageDataSource();
//        $states->each(function ($state){
//            $this->state($state['key'],$state['value'],$state['isJSExpression']);
//        });
//        $methods->each(function ($method,$key){
//            $this->methods($key,$method);
//        });
//        $sourceList->each(function ($method,$key){
//            $this->dataSource($key,$method);
//        });
//        $setup = $this->getSetupScript();
//        $this->setup($setup);
//        $this->setAttribute('lifeCycles',$this->lifeCycles);
//    }

    /**
     * 处理states数据
     * @return void
     */
    private function initHandler(): void
    {
        $states = $this->getStates("", $this->cacheKey);
        $methods = $this->getMethods($this->cacheKey);
        $sourceList = $this->getSourceList($this->cacheKey);
        foreach ($states as $key=>$state){
            $this->state($key,$state);
        }
        foreach ($methods as $key=>$method){
            $this->methods($key,$method['value']);
        }
        foreach ($sourceList as $key=>$method){
            $this->dataSource($key, $method['value']);
        }
        $this->setAttribute('lifeCycles',$this->lifeCycles);
    }

    /**
     * @return string
     */
    private function getSetupScript(): string
    {
        $this->watch("state","()=>{ app.setStates(state); }",['deep'=>true]);
        $setupMethods = implode("\n",$this->setupMethods);
        return <<<JS
function setup(setup) {
    const { state } = setup;
    const app = this.appStore();
    setup.onBeforeMount(()=>{
        const appState = app.getStates();
        if (appState!==undefined){
            this.setState(appState);
        }
    });
    $setupMethods
}
JS;
    }

    public function jsonSerialize():array
    {
        //处理数据
        $this->initHandler();
        return parent::jsonSerialize();
    }





}
